package com.syedu.day18;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * @author Administrator
 * @Description 反射获取方法信息并且调用方法
 * @createTime 2022/4/11 10:00
 */
public class MethodReflect {
    public static void main(String[] args) {
        try {
            //获取Class实例
            Class<Point> c = Point.class;
            //反射创建Point对象
            Point p = c.getConstructor().newInstance();

            //获取当前类所有公开的方法,包括父类继承的方法(不包含私有化方法)
            //Method[] methods = c.getMethods();
            //获取当前类中所有的方法,包括私有化(不包括父类的方法)
            Method[] methods = c.getDeclaredMethods();
            for (Method method : methods) {
                //System.out.println(method);

                //获取方法的修饰符,返回类型,方法名,参数列表
                String modifier = Modifier.toString(method.getModifiers());
                //获取方法的返回类型
                String returnTypeName = method.getReturnType().getName();
                //获取方法名称
                String methodName = method.getName();
                //获取方法的参数列表
                Class<?>[] parameterTypes = method.getParameterTypes();
                //编辑输出结果
                String result = modifier + " " + returnTypeName + " " + methodName + "(";
                if (parameterTypes != null && parameterTypes.length > 0) {
                    for (int i = 0; i < parameterTypes.length; i++) {
                        result += i == parameterTypes.length - 1 ? parameterTypes[i] : parameterTypes[i] + ",";
                    }
                }
                result += "){}";
                System.out.println(result);
            }

            System.out.println("-----------------------------------------------------------------");

            /**
             * 反射调用的方法
             */
            //1.获取void类型的空参方法
            //Method method1 = c.getMethod("method1", new Class[]{});
            Method method1 = c.getMethod("method1");
            //method1.invoke(p,new Object[]{});
            method1.invoke(p);

            //2.获取void类型的有参方法
            //Method method2 = c.getMethod("method2", new Class[]{int.class, int.class});
            //method2.invoke(p, new Object[]{10, 20}); //p.method2(10,20);
            c.getMethod("method2", int.class, int.class).invoke(p, 10, 20);

            //3.获取有返回值得方法
            //注意: 有返回值的方法,只需要在调用invoke后接一下参数即可
            Method method3 = c.getMethod("method3");
            Object returnValue = method3.invoke(p);
            System.out.println(returnValue);

            //4.获取私有化方法
            //注意: 私有化方法在获取时要注意获取方式getDeclaredMethod,并且还要开启权限
            Method method4 = c.getDeclaredMethod("method4");
            method4.setAccessible(true);
            method4.invoke(p);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}
